{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Managing pins"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%load_ext autoreload\n",
    "%autoreload 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import qiskit_metal as metal\n",
    "from qiskit_metal import designs, draw\n",
    "from qiskit_metal import MetalGUI, Dict, Headings\n",
    "Headings.h1('Welcome to Qiskit Metal')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design = designs.DesignPlanar()\n",
    "gui = MetalGUI(design)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First we create some transmon pockets to have a number of pins generated for use."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from qiskit_metal.qlibrary.qubits.transmon_pocket import TransmonPocket\n",
    "\n",
    "## Custom options for all the transmons\n",
    "options = dict(\n",
    "    # Some options we want to modify from the deafults\n",
    "    # (see below for defaults)\n",
    "    pad_width = '425 um', \n",
    "    pocket_height = '650um',\n",
    "    # Adding 4 connectors (see below for defaults)\n",
    "    connection_pads=dict( \n",
    "        a = dict(loc_W=+1,loc_H=+1), \n",
    "        b = dict(loc_W=-1,loc_H=+1, pad_height='30um'),\n",
    "        c = dict(loc_W=+1,loc_H=-1, pad_width='200um'),\n",
    "        d = dict(loc_W=-1,loc_H=-1, pad_height='50um')\n",
    "    )\n",
    ")\n",
    "\n",
    "## Create 4 transmons\n",
    "\n",
    "q1 = TransmonPocket(design, 'Q1', options = dict(\n",
    "    pos_x='+2.4mm', pos_y='+0.0mm', **options))\n",
    "q2 = TransmonPocket(design, 'Q2', options = dict(\n",
    "    pos_x='+0.0mm', pos_y='-0.9mm', orientation = '90', **options))\n",
    "q3 = TransmonPocket(design, 'Q3', options = dict(\n",
    "    pos_x='-2.4mm', pos_y='+0.0mm', **options))\n",
    "q4 = TransmonPocket(design, 'Q4', options = dict(\n",
    "    pos_x='+0.0mm', pos_y='+0.9mm', orientation = '90', **options))\n",
    "\n",
    "## Rebuild the design\n",
    "gui.rebuild()\n",
    "gui.autoscale()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Selecting the different components via the GUI shows the pins said component has. You can also see this via;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.components.Q1.pins.keys()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each pin contains a dictionary of information which can be used by other components or renderers. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.components.Q1.pins.a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can pass these pins into some components to auto generate connections, such as CPW lines."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from qiskit_metal.qlibrary.tlines.straight_path import RouteStraight\n",
    "\n",
    "c1 = RouteStraight(design, 'c1', type=\"Route\", options=dict(pin_inputs=dict(start_pin = dict(component = 'Q1',\n",
    "                                                                               pin = 'd'),\n",
    "                                                            end_pin=dict(component = 'Q2',\n",
    "                                                                                pin = 'c'))))\n",
    "gui.rebuild()\n",
    "gui.autoscale()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The example CPW also automatically generates it's own pins based on the pin inputs it was given. This is to allow for such a component to not\n",
    "be destroyed if the component it is attached to is deleted."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.components.c1.pins"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also see what active connections there are from the netlist. Pins that share the same net_id indicate they are connected. Pins that are not on the net list are currently open."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.net_info"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What happens if we try to pass in a component/pin combo that doesn't exist?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#A component that doesn't exist\n",
    "c2 = RouteStraight(design, 'c2', type=\"Route\", options=dict(pin_inputs = dict(start_pin = dict(component = 'NotReallyHere',\n",
    "                                                                               pin = 'd'),\n",
    "                                                            end_pin =dict(component = 'Q2',\n",
    "                                                                                pin = 'a'))))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#A pin that doesn't exist\n",
    "c3 = RouteStraight(design, 'c3', type=\"Route\", options=dict(pin_inputs = dict(start_pin = dict(component = 'Q1',\n",
    "                                                                               pin = 'NotReallyHere'),\n",
    "                                                            end_pin =dict(component = 'Q2',\n",
    "                                                                                pin = 'a'))))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or if try to pass in a pin that is already connected."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c4 = RouteStraight(design, 'c4', type=\"Route\", options=dict(pin_inputs = dict(start_pin = dict(component = 'Q1',\n",
    "                                                                               pin = 'b'),\n",
    "                                                            end_pin =dict(component = 'Q2',\n",
    "                                                                                pin = 'c'))))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "pin_inputs is the default dictionary for passing pins into a component, **BUT** how the dictionary is structured is component dependent. Using the above structure (eg. start_pin, end_pin) is suggested for any 2 port type connection, but you should always check the documentation for the specific component you are wanting to use."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Headings.h1('CPW Examples')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An example set showing some current functional CPW components, including both simple auto-routing and meandering"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "design.delete_all_components()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from qiskit_metal.qlibrary.terminations.open_to_ground import OpenToGround\n",
    "from qiskit_metal.qlibrary.tlines.framed_path import RouteFramed\n",
    "from qiskit_metal.qlibrary.tlines.straight_path import RouteStraight\n",
    "from qiskit_metal.qlibrary.tlines.meandered import RouteMeander"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "open_start_straight = OpenToGround(design,'Open_straight_start',options=Dict(pos_x='0um',pos_y='0um',orientation = '-90'))\n",
    "open_end_straight = OpenToGround(design,'Open_straight_end',options=Dict(pos_x='0um',pos_y='1500um',orientation = '90'))\n",
    "\n",
    "open_start_auto = OpenToGround(design,'Open_auto_start',options=Dict(pos_x='250um',pos_y='0um',orientation = '-90'))\n",
    "open_end_auto = OpenToGround(design,'Open_auto_end',options=Dict(pos_x='250um',pos_y='1500um',orientation = '0'))\n",
    "\n",
    "open_start_meander = OpenToGround(design,'Open_meander_start',options=Dict(pos_x='1000um',pos_y='0um',orientation = '-90'))\n",
    "open_end_meander = OpenToGround(design,'Open_meander_end',options=Dict(pos_x='1000um',pos_y='1500um',orientation = '90'))\n",
    "\n",
    "testStraight = RouteStraight(design,'straightTest',options=Dict(pin_inputs=Dict(\n",
    "                                                                    start_pin=Dict(\n",
    "                                                                        component = 'Open_straight_start',\n",
    "                                                                        pin = 'open'),\n",
    "                                                                    end_pin=Dict(\n",
    "                                                                        component = 'Open_straight_end',\n",
    "                                                                        pin = 'open')\n",
    "                                                                    )))\n",
    "\n",
    "testAuto = RouteFramed(design,'autoTest',options=Dict(pin_inputs=Dict(\n",
    "                                                                    start_pin=Dict(\n",
    "                                                                        component = 'Open_auto_start',\n",
    "                                                                        pin = 'open'),\n",
    "                                                                    end_pin=Dict(\n",
    "                                                                        component = 'Open_auto_end',\n",
    "                                                                        pin = 'open')\n",
    "                                                                    )))\n",
    "\n",
    "testMeander = RouteMeander(design,'meanderTest',options=Dict(pin_inputs=Dict(\n",
    "                                                                    start_pin=Dict(\n",
    "                                                                        component = 'Open_meander_start',\n",
    "                                                                        pin = 'open'),\n",
    "                                                                    end_pin=Dict(\n",
    "                                                                        component = 'Open_meander_end',\n",
    "                                                                        pin = 'open')\n",
    "                                                                    )))\n",
    "gui.rebuild()\n",
    "gui.autoscale()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
